import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import processing.core.PApplet;
import controlP5.ControlGroup;


public class DataDistributionObject extends DrawObject{

	CSVConn myconn;
	String columnName;
	int numBins = 100;
	int[] counts;
	boolean[] flags;
	int maxCount;
	int width,height;
	int geneCount;
	double minValue, maxValue;
	NumberFormat formatter;
	
	DataDistributionObject(String _columnName, PApplet applet, Canvas _parent, ControlGroup _group,
			float pos, float pos2, int _width, int _height) {
		super(applet, _parent, _group, pos, pos2);
		columnName = _columnName;
		width = _width;
		height = _height;
		initializeDistribution();
		
	}
	public void draw(PApplet theApplet) {
		//theApplet.scale(this.width/100, this.width/100);
		theApplet.fill(255,255,255,200);
		theApplet.noStroke();
		theApplet.rectMode(Main.CORNER);
		drawDistribution();
		
		
	}
	public void drawDistribution() {
		theApplet.stroke(0,0,255);
		theApplet.line((int)(width*.1), (int)(height*.5), (int)(width*.9), (int)(height*.5));
		theApplet.noFill();
		theApplet.beginShape();
		for(int i = 1; i<numBins-1; i++)
		{
			float x = (int)(width*.1) + (((float)i/(float)numBins)*(width*.8f));
			float y = (int)(height*.5) - (int)(height*.4)*((float)counts[i]/(float)maxCount);
			theApplet.vertex(x,y);
			if(flags[i]) 
			{
				theApplet.stroke(255,0,0);
				theApplet.ellipse(x,y,3,3);
				theApplet.stroke(0,0,255);
			}
		}
		theApplet.endShape();
		theApplet.textFont(Main.font12);
		theApplet.text("Number of Genes: " + geneCount, width*.03f, height*.6f);
		theApplet.text("Maximum Value: " + formatter.format(maxValue), width*.03f, height*.6f + 14);
		theApplet.text("Minimum Value: " + formatter.format(minValue), width*.03f, height*.6f + 28);
	}
	
	public void initializeDistribution() {
		myconn = new CSVConn("../data");
		if(myconn.query("SELECT " + columnName  + " FROM partial_genes4329") == 1) {
			ResultSet results = myconn.getResults();
			ArrayList<Double> dataValues = new ArrayList<Double>();
			try {				
				while (results.next())
				{
					dataValues.add(results.getDouble(columnName));
				}
			} 
			catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Collections.sort(dataValues);

			geneCount = dataValues.size();
			minValue = dataValues.get(0);
			maxValue = dataValues.get(geneCount-1);
			
			double min = dataValues.get((int)(dataValues.size()*.01));
			double max = dataValues.get((int)(dataValues.size()*.99));			
			double interval = (max-min)/(float)(numBins-1);
			counts = new int[numBins];
			double currentCutoff = min;
			int currentBin = 0;
			for(int i = 0; i< dataValues.size(); i++)
			{			
				while(dataValues.get(i) > currentCutoff  && currentBin < (numBins - 1))
				{
					currentCutoff += interval;
					currentBin++;
				}
				counts[currentBin] ++;
			}
			int[] countsCopy = new int[numBins];
			for(int i= 0; i< numBins; i++)
				countsCopy[i] = counts[i];
			Arrays.sort(countsCopy);
			maxCount = countsCopy[numBins - 1];
			if( maxCount == counts[0] || maxCount == counts[numBins-1])
				maxCount= countsCopy[numBins - 2];
			if( maxCount == counts[0] || maxCount == counts[numBins-1])
				maxCount= countsCopy[numBins - 3];		
			
			flags = new boolean[numBins];
			for(int i = 0; i< numBins; i++)
				flags[i] = false;
			
			//gets rid of spikes (usually at 0 value)
			maxCount = countsCopy[numBins - 2];
			for(int i= 0; i< numBins; i++)
				if(counts[i] > maxCount)
				{
					counts[i]= maxCount;
					flags[i] =true;					
				}
			
			formatter = new DecimalFormat("0.##E0");
		}
	}
}
